home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / games_d / rtanksrc.zip / NEWTERP.C < prev    next >
C/C++ Source or Header  |  1995-03-07  |  17KB  |  628 lines

  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <dtypes.h>
  5. #include <string.h>
  6. #include <bios.h>
  7. #include <conio.h>
  8.  
  9. #include "code.h"
  10. #include "host.h"
  11. #include "newload.h"
  12. #include "callasm.h"
  13. #include "newterp.h"
  14. #include "tconfig.h"
  15. #include "tiles.h"
  16.  
  17. #define BASERANGE 40
  18.  
  19. extern PLAYER players[10];
  20. extern p_TANK point[10];
  21. extern BOOL update_scr;
  22. extern int num_players;
  23. extern int setbullet;
  24.  
  25. BOOL usedhit;
  26.  
  27. /*<f>----------------------------------------
  28.  * FUNCTION: <s> void init_interpreter(p_TANK t)
  29.  * PURPOSE : Initilize parts of T structure used by interpreter
  30.  *         :
  31.  * CREATION: 01/09/1989 07:16:16
  32.  */
  33. void init_interpreter(p_TANK t)
  34. {
  35.  
  36.    memset(t->var,0,sizeof(t->var));
  37.    t->cline=t->prog;
  38.    t->depth=0;
  39.    t->bwait=0;
  40.    t->boom=FALSE;
  41.    t->jiggle=FALSE;
  42.    t->hit=FALSE;
  43.    t->nhits=0;
  44.    t->cweapon=0;
  45.    t->nomove=FALSE;
  46.    t->channel=0;
  47.    t->automove = FALSE;
  48.    t->autolock = FALSE;
  49.    t->jammer   = FALSE;
  50.    t->blockage = 0;
  51.  
  52.    clear_channel(&t->station);
  53.  
  54. } /* void init_interpreter(p_TANK t) */
  55.  
  56.  /*<f>----------------------------------------
  57.   * FUNCTION: <s> void interprete(p_TANK t, p_PLAYER p)
  58.   * PURPOSE : Main interpreter function
  59.   *         :
  60.   * CREATION: 01/09/1989 07:19:42
  61.   */
  62. void interprete(p_TANK t, p_PLAYER p)
  63. {
  64. p_LINE cl;
  65. BOOL   next;
  66. int rx1, rx2, rx3;
  67.  
  68.    if (!p->active) return;
  69.  
  70.    cl=t->cline;
  71.  
  72.    if (cl==(0L)) {
  73.        p->active=FALSE;
  74.        t->died=biostime(0,0);
  75.    }
  76.  
  77. /*
  78.    gotoxy(1,1); explain_line(cl);
  79. */
  80.  
  81.    next=TRUE; usedhit=FALSE;
  82.  
  83.    restore_under_tank(t);
  84.  
  85.    t->var[CWHEREX]  =t->px;
  86.    t->var[CWHEREY]  =t->py;
  87.    t->var[CCGDIR]   =t->cgpoint;
  88.    t->var[CCTDIR]   =t->cpoint;
  89.    t->var[CHIT]     =t->hit;
  90.    t->var[CNOMOVE]  =t->nomove;
  91.    t->var[CBLOCKAGE]=t->blockage;
  92.    t->var[CMESSAGE] =any_messages(&t->station);
  93.  
  94.    if (t->automove) {
  95.        move_tank(t);
  96.        update_scr=TRUE;
  97.    }
  98.  
  99.    switch(cl->command) {
  100.  
  101.       case BAD     : gotoxy(15,23);
  102.                      printf("BAD command line encountered");
  103.                      break;
  104.  
  105.       case _JLT    : if (get_arg(t,&cl->arg1) < get_arg(t,&cl->arg2)) {
  106.                         next=FALSE;
  107.                         t->cline=get_line_arg(&cl->arg3);
  108.                      }
  109.                      break;
  110.  
  111.       case _JGT    : if (get_arg(t,&cl->arg1) > get_arg(t,&cl->arg2)) {
  112.                         next=FALSE;
  113.                         t->cline=get_line_arg(&cl->arg3);
  114.                      }
  115.                      break;
  116.  
  117.       case _GOTO   : t->cline=get_line_arg(&cl->arg1);
  118.                      next=FALSE;
  119.                      break;
  120.  
  121.       case _JEQ    : if (get_arg(t,&cl->arg1) == get_arg(t,&cl->arg2)) {
  122.                         next=FALSE;
  123.                         t->cline=get_line_arg(&cl->arg3);
  124.                      }
  125.                      break;
  126.  
  127.       case _JNEQ   : if (get_arg(t,&cl->arg1) != get_arg(t,&cl->arg2)) {
  128.                         next=FALSE;
  129.                         t->cline=get_line_arg(&cl->arg3);
  130.                      }
  131.                      break;
  132.  
  133.       case _CALL   : do_call(t,&cl->arg1);
  134.                      next=FALSE;
  135.                      break;
  136.  
  137.       case _MOVE   : if (!t->automove) {
  138.                          move_tank(t);
  139.                          update_scr=TRUE;
  140.                      }
  141.                      break;
  142.  
  143.       case _LEFT   : turn_tank_left(t);
  144.                      break;
  145.  
  146.       case _GLEFT  : turn_gun_left(t);
  147.                      break;
  148.  
  149.       case _RIGHT  : turn_tank_right(t);
  150.                      break;
  151.  
  152.       case _GRIGHT : turn_gun_right(t);
  153.                      break;
  154.  
  155.       case _FIRE   : shoot(t);
  156.                      break;
  157.  
  158.       case _RETURN : do_return(t);
  159.                      break;
  160.  
  161.       case _SET    : store(t,&cl->arg1,get_arg(t,&cl->arg2));
  162.                      break;
  163.  
  164.       case _ADD    : store(t,&cl->arg1,
  165.                            get_arg(t,&cl->arg1)+get_arg(t,&cl->arg2));
  166.                      break;
  167.  
  168.       case _RAND   : store(t,&cl->arg1,1+(rand() % get_arg(t,&cl->arg2)));
  169.                      break;
  170.  
  171.       case _SELECT : t->cweapon=get_arg(t,&cl->arg1)-1;
  172.                      break;
  173.  
  174.       case _CHANNEL: t->channel =get_arg(t,&cl->arg1);
  175.                      t->var[CCHANNEL] = t->channel;
  176.                      break;
  177.  
  178.       case _AUTO   : t->automove=get_arg(t,&cl->arg1);
  179.                      break;
  180.  
  181.       case _LOCK   : t->autolock=get_arg(t,&cl->arg1);
  182.                      break;
  183.  
  184.       case _JAMMER : t->jammer=get_arg(t,&cl->arg1);
  185.                      break;
  186.  
  187.       case _TX     : transmit(t, get_arg(t,&cl->arg1),
  188.                                  get_arg(t,&cl->arg2),
  189.                                  get_arg(t,&cl->arg3)
  190.                              );
  191.                      break;
  192.  
  193.       case _RX     : read_message(&t->station, &rx1, &rx2, &rx3);
  194.                      store(t,&cl->arg1,rx1);
  195.                      store(t,&cl->arg2,rx2);
  196.                      store(t,&cl->arg3,rx3);
  197.                      break;
  198.  
  199.       case _FACE   : rx1=best_turn(t->cpoint,get_arg(t,&cl->arg1));
  200.                      if (rx1==1)
  201.                          turn_tank_left(t);
  202.                      else if (rx1==2)
  203.                          turn_tank_right(t);
  204.                      break;
  205.  
  206.       case _AIM    : rx1=best_turn(t->cgpoint,get_arg(t,&cl->arg1));
  207.                      if (rx1==1)
  208.                          turn_gun_left(t);
  209.                      else if (rx1==2)
  210.                          turn_gun_right(t);
  211.                      break;
  212.  
  213.       case _CONV   : store(t,&cl->arg3,do_conv(t,get_arg(t,&cl->arg1),get_arg(t,&cl->arg2)));
  214.                      break;
  215.  
  216.       case _RADAR  : if (p->extrasType[RADAR]>0)
  217.                          store(t, &cl->arg1, check_radar(t) );
  218.                      break;
  219.  
  220.       case _SCOPE  : if (p->extrasType[WBSCAN]>0)
  221.                         store(t, &cl->arg1, check_scope(t));
  222.                      break;
  223.  
  224.       case _SCAN   : if (p->extrasType[SCANNER]>0)
  225.                         store(t, &cl->arg1,check_scan(t,get_arg(t,&cl->arg2)));
  226.                      break;
  227.  
  228.    }
  229.  
  230.    if (usedhit)
  231.       t->hit=FALSE;
  232.  
  233.    if (next)
  234.       t->cline=t->cline->nextline;
  235.  
  236.    display_tank(t);
  237.  
  238. } /* void interprete(p_TANK t, p_PLAYER p) */
  239.  
  240. /*-------------------------------------
  241.  * Function : int best_turn(int curr, int dest)
  242.  * Purpose  : Calculate which is the best direction to turn to face dest
  243.  * Date     : 02/15/1989 22:05:17
  244.  */
  245. int best_turn(int curr, int dest)
  246. {
  247. int turn, num1, num2;
  248.  
  249.    if (curr==dest)
  250.        turn=0;
  251.    else {
  252.        if (curr > dest) {
  253.            num1 = curr-dest;
  254.            num2 = 8+dest-curr;
  255.        } else {
  256.            num1 = 8+curr-dest;
  257.            num2 = dest-curr;
  258.        }
  259.  
  260.        if (num1 < num2)
  261.            turn = 1; /* Move Left, counter-clockwise */
  262.        else if (num1 > num2)
  263.            turn = 2; /* Move right */
  264.        else turn = random(2)+1;       /* same dist, any way! */
  265.    }
  266.    return turn;
  267. } /* int best_turn(int curr, int dest) */
  268.  
  269. /*-------------------------------------
  270.  * Function : void turn_tank_left(p_TANK t)
  271.  * Purpose  : Turn tank counter-clockwise and update registers
  272.  * Date     : 02/15/1989 21:55:11
  273.  */
  274. void turn_tank_left(p_TANK t)
  275. {
  276.     spin(&t->cpoint,-1);
  277.     if (t->autolock)
  278.         turn_gun_left(t);
  279.  
  280. } /* void turn_tank_left(p_TANK t) */
  281.  
  282. /*-------------------------------------
  283.  * Function : void turn_tank_right(p_TANK t)
  284.  * Purpose  : Turn tank in clockwise direction
  285.  * Date     : 02/15/1989 21:55:57
  286.  */
  287. void turn_tank_right(p_TANK t)
  288. {
  289.     spin(&t->cpoint,1);
  290.     if (t->autolock)
  291.         turn_gun_right(t);
  292.  
  293. } /* void turn_tank_right(p_TANK t) */
  294.  
  295. /*-------------------------------------
  296.  * Function : void turn_gun_left(p_TANK t)
  297.  * Purpose  : Turn tank's gun in counter-clockwise direction
  298.  * Date     : 02/15/1989 21:56:21
  299.  */
  300. void turn_gun_left(p_TANK t)
  301. {
  302.   spin(&t->cgpoint,-1);
  303.   update_scr=TRUE;
  304. } /* void turn_gun_left(p_TANK t) */
  305.  
  306. /*-------------------------------------
  307.  * Function : void turn_gun_right(p_TANK t)
  308.  * Purpose  : Turn tanks gun in clockwise direction
  309.  * Date     : 02/15/1989 21:56:50
  310.  */
  311. void turn_gun_right(p_TANK t)
  312. {
  313.    spin(&t->cgpoint,1);
  314.    update_scr=TRUE;
  315. } /* void turn_gun_right(p_TANK t) */
  316.  
  317. /*-------------------------------------
  318.  * Function : void transmit(p_TANK t, int tx1, int tx2, int tx3)
  319.  * Purpose  : Transmit tx1,2,&3 to any active listening tanks
  320.  * Date     : 02/13/1989 23:19:34
  321.  */
  322. void transmit(p_TANK t, int tx1, int tx2, int tx3)
  323. {
  324. int a;
  325.  
  326.     for (a=0; a<num_players; a++)
  327.       if (players[a].active && t!=point[a] && point[a]->channel==t->channel)
  328.           add_message_to_channel(&point[a]->station, tx1, tx2, tx3);
  329.  
  330. } /* void transmit(p_TANK t, int tx1, int tx2, int tx3) */
  331.  
  332. /*<f>----------------------------------------
  333.  * FUNCTION: <s> void store(p_TANK t, p_ARG a, int n)
  334.  * PURPOSE : Store value N into argument A of tank T
  335.  *         :
  336.  * CREATION: 01/09/1989 07:28:27
  337.  */
  338. void store(p_TANK t, p_ARG a, int n)
  339. {
  340.    if (a->atype!=SYMBOL) {
  341.       gotoxy(15,23);
  342.       printf("Attempt to assign to constant");
  343.    } else
  344.       t->var[a->value]=n;
  345. } /* void store(p_TANK t, p_ARG a, int n) */
  346.  
  347. /*<f>----------------------------------------
  348.  * FUNCTION: <s> int get_arg(p_TANK t, p_ARG a)
  349.  * PURPOSE : Get the contents of value pointed to by argument A
  350.  *         :
  351.  * CREATION: 01/09/1989 07:31:18
  352.  */
  353. int get_arg(p_TANK t, p_ARG a)
  354. {
  355. int ret;
  356.  
  357.    ret=0;
  358.    if (a->atype==SYMBOL) {
  359.       ret=t->var[a->value];
  360.       if (a->value==CHIT)
  361.          usedhit=TRUE;
  362.    } else if (a->atype==CONSTANT)
  363.       ret=a->value;
  364.    else {
  365.        gotoxy(15,23);
  366.        printf("Attempt to return line_ref in integer");
  367.    }
  368.  
  369.    return ret;
  370.  
  371. } /* int get_arg(p_TANK t, p_ARG a) */
  372.  
  373. /*<f>----------------------------------------
  374.  * FUNCTION: <s> void spin(int *v, int dir)
  375.  * PURPOSE : Spin a tank or gun clockwise or counter-clockwise
  376.  *         :
  377.  * CREATION: 01/09/1989 07:44:59
  378.  */
  379. void spin(int *v, int dir)
  380. {
  381.    (*v)+=dir;
  382.    if (*v==0) *v=8;
  383.    if (*v==9) *v=1;
  384. } /* void spin(int *v, int dir) */
  385.  
  386. /*<f>----------------------------------------
  387.  * FUNCTION: <s> p_LINE get_line_arg(p_ARG a)
  388.  * PURPOSE : Return pointer to next line in arg A
  389.  *         :
  390.  * CREATION: 01/09/1989 07:51:05
  391.  */
  392. p_LINE get_line_arg(p_ARG a)
  393. {
  394. p_LINE ret;
  395.  
  396.    ret=0L;
  397.    if (a->atype!=LINEREF) {
  398.       gotoxy(15,23);
  399.       printf("Returning lineref of a non-lineref argument");
  400.    } else ret=a->linedest;
  401.    return (ret);
  402.  
  403. } /* p_LINE get_line_arg(p_ARG a) */
  404.  
  405. /*<f>----------------------------------------
  406.  * FUNCTION: <s> void do_call(p_TANK pb, p_ARG pa)
  407.  * PURPOSE : Call subroutine at PA
  408.  *         :
  409.  * CREATION: 11/29/1988 14:21:52
  410.  */
  411. void do_call(p_TANK pb, p_ARG pa)
  412. {
  413.    if (pb->depth>19) {
  414.       gotoxy(15,23);
  415.       printf("Too many CALL's");
  416.       return;
  417.    }
  418.  
  419.    pb->gosub[pb->depth++]=pb->cline;
  420.    pb->cline=get_line_arg(pa);
  421.  
  422. } /* void do_call(p_TANK pb, p_ARG pa) */
  423.  
  424. /*<f>----------------------------------------
  425.  * FUNCTION: <s> void do_return(p_TANK pb)
  426.  * PURPOSE : Do a return
  427.  *         :
  428.  * CREATION: 11/29/1988 14:23:35
  429.  */
  430. void do_return(p_TANK pb)
  431. {
  432.    if (pb->depth<1) {
  433.       gotoxy(15,23);
  434.       printf("RETURN without CALL");
  435.       return;
  436.    }
  437.    pb->cline=pb->gosub[--pb->depth];
  438. } /* void do_return(p_TANK pb) */
  439.  
  440. /*<f>----------------------------------------
  441.  * FUNCTION: <s> void shoot(p_TANK p)
  442.  * PURPOSE : Fire a bullet in current direction
  443.  *         :
  444.  * CREATION: 12/05/1988 19:16:09
  445.  */
  446. void shoot(p_TANK p)
  447. {
  448.    switch (p->cweapon) {
  449.  
  450.        case ROCKET : setbullet = ROCKET1 + p->cpoint-1;
  451.                      break;
  452.  
  453.        case MACH16 : setbullet = BMACH16;
  454.                      break;
  455.  
  456.        case LASER  : setbullet = LASER15 + ((p->cpoint-1)%4);
  457.                      break;
  458.  
  459.        case CANNON : setbullet = CANNONBL;
  460.                      break;
  461.  
  462.        default     : setbullet = BMACH8;
  463.                      break;
  464.    }
  465.  
  466.    switch (p->cgpoint) {
  467.       case 1 : init_bullet(p->px,p->py,0,-1,BASERANGE);
  468.                break;
  469.       case 2 : init_bullet(p->px+1,p->py,1,-1,BASERANGE);
  470.                break;
  471.       case 3 : init_bullet(p->px+1,p->py,1,0,BASERANGE);
  472.                break;
  473.       case 4 : init_bullet(p->px+1,p->py+1,1,1,BASERANGE);
  474.                break;
  475.       case 5 : init_bullet(p->px,p->py+1,0,1,BASERANGE);
  476.                break;
  477.       case 6 : init_bullet(p->px,p->py+1,-1,1,BASERANGE);
  478.                break;
  479.       case 7 : init_bullet(p->px,p->py,-1,0,BASERANGE);
  480.                break;
  481.       case 8 : init_bullet(p->px,p->py,-1,-1,BASERANGE);
  482.                break;
  483.    }
  484. } /* void v_shoot(p_TANK p) */
  485.  
  486. /*<f>----------------------------------------
  487.  * FUNCTION: <s> int check_radar(p_TANK p)
  488.  * PURPOSE : Look around for close tanks
  489.  *         : and return distance
  490.  * CREATION: 12/06/1988 11:49:48
  491.  */
  492. int check_radar(p_TANK p)
  493. {
  494. unsigned int f,d,a;
  495. int x,y;
  496.  
  497.    p->var[CTEAM]=ALLOUT;
  498.    for (f=40, a=0; a<num_players; a++)
  499.       if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
  500.          x=abs(point[a]->px - p->px);
  501.          y=abs(point[a]->py - p->py);
  502.          d=(x<y) ? y : x;
  503.          if (d<f) {
  504.             p->var[CTEAM]=point[a]->team;
  505.             f=d;
  506.          }
  507.       }
  508.    return ((f==40) ? 0 : f);
  509. } /* int check_radar(p_TANK p) */
  510.  
  511. /*<f>----------------------------------------
  512.  * FUNCTION: <s> int check_scope(p_TANK p)
  513.  * PURPOSE : Return the direction to the closest tank
  514.  *         :
  515.  * CREATION: 01/13/1989 12:55:52
  516.  */
  517. int check_scope(p_TANK p)
  518. {
  519. int f,d,a,t;
  520. int x,y;
  521.  
  522.    for (t=-1, f=999, a=0; a<num_players; a++)
  523.       if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
  524.          x=abs(point[a]->px - p->px);
  525.          y=abs(point[a]->py - p->py);
  526.          d=(x<y) ? y : x;
  527.          if (d<f) {
  528.             p->var[CTEAM]=point[a]->team;
  529.             f=d; t=a;
  530.          }
  531.       }
  532.  
  533.    if (f==999) {
  534.       p->var[CTEAM]=ALLOUT;
  535.       f=0;
  536.    } else {
  537.       x=point[t]->px - p->px;
  538.       y=point[t]->py - p->py;
  539.  
  540.       if (x==0) {
  541.          if (y<0) f=1; else f=5;
  542.       } else if (y==0) {
  543.          if (x<0) f=7; else f=3;
  544.       } else if (x<0) {
  545.          if (y<0) f=8; else f=6;
  546.       } else {
  547.          if (y<0) f=2; else f=4;
  548.       }
  549.    }
  550.    return f;
  551.  
  552. } /* int check_scope(p_TANK p) */
  553.  
  554. /*<f>----------------------------------------
  555.  * FUNCTION: <s> int do_conv(p_TANK p, int x, int y)
  556.  * PURPOSE : Return the direction to the closest tank
  557.  *         :
  558.  * CREATION: 01/13/1989 12:55:52
  559.  */
  560. int do_conv(p_TANK p, int x, int y)
  561. {
  562. int f,xx,yy;
  563.  
  564.       f =0;
  565.  
  566.       xx=x - p->px;
  567.       yy=y - p->py;
  568.  
  569.       if (xx==0) {
  570.          if (yy<0) f=1; else f=5;
  571.       } else if (yy==0) {
  572.          if (xx<0) f=7; else f=3;
  573.       } else if (xx<0) {
  574.          if (yy<0) f=8; else f=6;
  575.       } else {
  576.          if (yy<0) f=2; else f=4;
  577.       }
  578.    return f;
  579. }
  580. /* int do_conv(p_TANK p, int x, int y) */
  581.  
  582. /*<f>----------------------------------------
  583.  * FUNCTION: <s> int check_scan(p_TANK p, int n)
  584.  * PURPOSE : Perform a scan for robot p in direction n
  585.  *         :
  586.  * CREATION: 12/06/1988 14:02:03
  587.  */
  588. int check_scan(p_TANK p, int n)
  589. {
  590. int dx,dy,a,adx, ady;
  591. BOOL fuzzy;
  592.  
  593.    for (a=0; a<num_players; a++)
  594.       if (players[a].active && p!=point[a] && (point[a]->team!=p->team || p->team==ALLOUT)) {
  595.  
  596.          dx=p->px-point[a]->px;
  597.          dy=p->py-point[a]->py;
  598.          adx=abs(dx);
  599.          ady=abs(dy);
  600.          if (abs(adx-ady)<2) fuzzy=TRUE; else fuzzy=FALSE;
  601.  
  602.          p->var[CTEAM]=point[a]->team;
  603.  
  604.          switch (n) {
  605.             case 1 : if ((adx<2) && (dy> 0)) return TRUE;
  606.                      break;
  607.             case 2 : if ((dx< 0) && (dy> 0) && fuzzy) return TRUE;
  608.                      break;
  609.             case 3 : if ((dx< 0) && (ady<2)) return TRUE;
  610.                      break;
  611.             case 4 : if ((dx< 0) && (dy< 0) && fuzzy) return TRUE;
  612.                      break;
  613.             case 5 : if ((adx<2) && (dy< 0)) return TRUE;
  614.                      break;
  615.             case 6 : if ((dx> 0) && (dy< 0) && fuzzy) return TRUE;
  616.                      break;
  617.             case 7 : if ((dx> 0) && (ady<2)) return TRUE;
  618.                      break;
  619.             case 8 : if ((dx> 0) && (dy> 0) && fuzzy) return TRUE;
  620.                      break;
  621.          }
  622.       }
  623.  
  624.       p->var[CTEAM]=ALLOUT;
  625.       return FALSE;
  626.  
  627. } /* int check_scan(p_TANK p, int n) */
  628.